package com.shujia.scala

object Demo15Fun {
  def main(args: Array[String]): Unit = {
    /**
     * 面向对象编程
     * 将一个对象传来传去
     * 1、以对象作为参数
     * 2、以对象作为返回值
     * 需要明确对象的类型，需要缺点参数和返回值的类型，当然可以使用多态
     *
     * 面向函数编程  --- 高阶函数
     * 将一个函数传来传去
     * 1、以函数作为参数 -- 重点
     * 2、以函数作为返回值
     * 需要明确函数的类型
     *
     */

    /**
     * 函数的类型
     * 函数的而类型由参数类型和返回值类型一起确定
     *
     * intToString是一个参数为Int返回值为String类型的函数
     * 函数类下表示方式： Int => String
     * => 前面是参数类型
     * => 后面是返回值类型
     */

    def intToString(i: Int): String = {
      i.toString
    }

    val str: String = intToString(100)

    println(str)

    //将一个函数赋值给一个变量
    val f: Int => String = intToString

    //调用函数
    val str1: String = f(200)
    println(str1)


    /**
     * 1、以函数作为参数
     *
     * fun: 是一个参数为一个函数，没有返回值的函数
     * 参数的函数的类型为：参数Int返回值为String类型的函数
     */

    def fun(f: Int => Int): Unit = {
      //调用传进来的函数
      println("调用f")
      val j: Int = f(100)
      println(j)
    }

    //定义一个参数为Int返回值为Int类型的函数
    def intToInt(i: Int): Int = {
      println("执行intToInt")
      i * 100
    }

    println("调用fun")
    //调用fun需要传入一个函数
    fun(intToInt)
    println("=" * 100)

    def intToInt2(i: Int): Int = {
      println("执行intToInt2")
      i + 100
    }
    //可以多次调用，传入不同的函数
    fun(intToInt2)


    println("=" * 100)

    /**
     * 使用lambda表达式调用函数
     *
     */


    def fun1(f: Int => Int): Unit = {
      //调用传进来的函数
      println("调用f")
      val j: Int = f(100)
      println(j)
    }

    fun1((i: Int) => {
      println("执行lambda表达式")
      i - 100
    })

  }

}
